package com.yuyou.tas.report.service.impl;

import com.yuyou.tas.report.entity.ExamModelBlock;
import com.yuyou.tas.report.mapper.ExamModelBlockMapper;
import com.yuyou.tas.report.mapper.ExamModelReportKnowledgeIMapper;
import com.yuyou.tas.report.mapper.ExamModelReportMapper;
import com.yuyou.tas.report.mapper.ExamModelReportQuesMapper;
import com.yuyou.tas.report.service.IExamModelQuesService;
import com.yuyou.tas.report.service.IExamModelRangeService;
import com.yuyou.tas.report.service.IExamModelReportService;
import com.yuyou.tas.report.service.IExamModelService;
import com.yuyou.tas.report.vo.ExcelErr;
import com.yuyou.tas.report.vo.ExcelStudentScore;
import com.yuyou.tas.report.vo.resp.*;
import com.yuyou.tas.service.api.admin.entity.CommDataConfig;
import com.yuyou.tas.service.api.lesson.entity.*;
import com.yuyou.tas.service.api.lesson.service.BaseDataAPI;
import com.yuyou.tas.service.api.lesson.service.CommDataConfigAPI;
import com.yuyou.tas.service.api.lesson.service.LessonAPI;
import com.yuyou.tas.service.api.lesson.service.LessonClassAPI;
import com.yuyou.tas.service.api.lesson.vo.LessonClassVo;
import com.yuyou.tas.service.api.report.dto.ExamModelVo;
import com.yuyou.tas.service.api.report.entity.*;
import com.yuyou.tas.util.enums.admin.CommDataConfigEnums;
import com.yuyou.tas.util.enums.report.ExamModelEnums;
import com.yuyou.tas.util.exception.BusinessException;
import com.yuyou.tas.util.office.edit.DataUtils;
import com.yuyou.tas.util.tool.*;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.xssf.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service
public class ExamModelReportServiceImpl implements IExamModelReportService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private static final int reportBatchSize = 20;

    @Autowired
    private ExamModelReportMapper examModelReportMapper;

    @Autowired
    private ExamModelReportQuesMapper examModelReportQuesMapper;

    @Autowired
    private ExamModelBlockMapper examModelBlockMapper;

    @Autowired
    private CommDataConfigAPI commDataConfigService;

    @Autowired
    private BaseDataAPI lessonApi;

    @Autowired
    private IExamModelService examModelService;

    @Autowired
    private IExamModelRangeService examModelRangeService;

    @Autowired
    private IExamModelQuesService examModelQuesService;

    @Autowired
    private LessonClassAPI lessonClassAPI;

    @Autowired
    private LessonAPI lessonAPI;

    @Autowired
    private ExamModelReportKnowledgeIMapper examModelReportKnowledgeIMapper;


    @Override
    public int deleteByPrimaryKey(Long id) {
        return examModelReportMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int insert(ExamModelReport record) {
        return examModelReportMapper.insert(record);
    }

    @Override
    public ExamModelReport selectByPrimaryKey(Long id) {
        return examModelReportMapper.selectByPrimaryKey(id);
    }

    @Override
    public int updateByPrimaryKeySelective(ExamModelReport record) {
        return examModelReportMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    @Transactional(rollbackFor=Exception.class)
    public XSSFWorkbook saveExcel(InputStream in , Long organId) throws Exception{
        String[][] data = DataUtils.getData(1 , in);
        XSSFWorkbook excel = new XSSFWorkbook() ;
        List<ExcelErr> list = new ArrayList<>();
        if(data != null && data.length > 0){
            logger.info("成绩导入行数："+data.length);

            /*List<BaseSchool> schools = lessonApi.getSchoolByOrganId(organId);//机构下所有班级
            Map<String , BaseSchool> schoolMap = BeanUtils.toMap(schools , "name");*/

            List<BaseTrimester> trimesters = lessonApi.findTrimByOran(organId);//获取机构下所有学期
            Map<String , BaseTrimester> trimesterMap = BeanUtils.toMap(trimesters , "name");

            List<BaseSection> sections = lessonApi.findSectionName(new HashMap<>());//获取所有年级
            Map<String , BaseSection> sectionMap = BeanUtils.toMap(sections , "name");

            List<CommDataConfig> subjects = commDataConfigService.findUseByCategory(CommDataConfigEnums.category.subject.getValue());//获取所有年级
            Map<String , CommDataConfig> subjectMap = BeanUtils.toMap(subjects , "name");

            List<CommDataConfig> timeTypes = commDataConfigService.findUseByCategory(CommDataConfigEnums.category.timeType.getValue());//获取所有期类型
            Map<String , CommDataConfig> timeTypesMap = BeanUtils.toMap(timeTypes , "name");

            /*List<Student> students = lessonApi.selectStudentByOrganId(organId);//获取机构下所有所学生
            Map<String , Student> studentMap = BeanUtils.toMap(students , "studentNo");*/

            List<LessonClassVo> classes = lessonApi.findLessonClassByOrganId(organId);
            Map<String , LessonClassVo> classMap = BeanUtils.toMap(classes , "num");

            List<ExamModelVo> examModelVos = examModelService.selectByOrganId(organId);

            //标准试卷
            List<ExamModelVo> stands = examModelVos.stream().filter(e -> e.getRangeType() == ExamModelEnums.rangeType.stand.getValue()).collect(Collectors.toList());
            Map<String , List<ExamModelVo>> examModelVosMap = BeanUtils.toGroup(stands , "keyStr");
            examModelVosMap.forEach((k,v)->{
                if(v.size() > 1){
                    throw new BusinessException("标准模板-keyStr："+k+"对应出多个试卷模板：["+v.stream().map(p -> p.getName()).collect(Collectors.joining(","))+"]");
                }
            });

            //自定义试卷
            List<ExamModelVo> defind = examModelVos.stream().filter(e -> e.getRangeType() == ExamModelEnums.rangeType.defind.getValue()).collect(Collectors.toList());
            Map<String , ExamModelVo> examModelVoMap = BeanUtils.toMap(stands , "keyStr");
            Map<Long , ExamModelVo> examModelIdMap = BeanUtils.toMap(defind , "id");

            List<ExamModelRange> ranges = examModelRangeService.getByOrganId(organId);
            Map<Long , ExamModelRange> rangeMap = BeanUtils.toMap(ranges , "lessonClassId");

            List<ExamModelQues> examModelQues = examModelService.selectQuesByOrganId(organId);
            Map<Long , List<ExamModelQues>> quesGroup = BeanUtils.toGroup(examModelQues , "examModelId");

            List<ExamModelReport> reportList = new ArrayList<>(reportBatchSize);
            List<ExamModelReportQues> reportQuesList = new ArrayList<>();

            for (int i = 0 ; i < data.length ; i++){
                if(StringUtils.isEmpty(data[i][0])){throw new BusinessException("第"+(1+i)+"行的期数不能为空"); }
                BaseTrimester bt = trimesterMap.get(data[i][0].trim());
                if(bt == null){
                    checkQues(data[i] , null, null ,"期数名称:"+data[i][0].trim()+",在系统中查找不到",list);
                    continue;
//                    throw new BusinessException("第"+(1+i)+"行的期数名称:"+data[i][0].trim()+",在系统中查找不到");
                }

                if(StringUtils.isEmpty(data[i][1])){throw new BusinessException("第"+(1+i)+"行的类型不能为空"); }
                CommDataConfig timeType = timeTypesMap.get(data[i][1].trim());
                if(timeType == null){
                    checkQues(data[i] , null, null ,"期类型名称:"+data[i][1].trim()+",在系统中查找不到",list);
                    continue;
//                    throw new BusinessException("第"+(1+i)+"行的类型名称在系统中查找不到");
                }

                /*if(StringUtils.isEmpty(data[i][2])){throw new BusinessException("第"+i+"行的校区不能为空"); }
                BaseSchool bs = schoolMap.get(data[i][2]);
                if(bs == null){throw new BusinessException("第"+i+"行的校区名称在系统中查找不到"); }*/

                if(StringUtils.isEmpty(data[i][3])){throw new BusinessException("第"+(1+i)+"行的年级不能为空"); }
                BaseSection baseSection = sectionMap.get(data[i][3].trim());
                if(baseSection == null){
                    checkQues(data[i] , null, null ,"年纪名称:"+data[i][3].trim()+",在系统中查找不到",list);
                    continue;
//                    throw new BusinessException("第"+(1+i)+"行的年级名称在系统中查找不到");
                }

                if(StringUtils.isEmpty(data[i][4])){throw new BusinessException("第"+(1+i)+"行的科目不能为空"); }
                CommDataConfig subject = subjectMap.get(data[i][4].trim());
                if(subject == null){

                    checkQues(data[i] , null, null ,"科目名称:"+data[i][4].trim()+",在系统中查找不到",list);
                    continue;
//                    throw new BusinessException("第"+(1+i)+"行的科目名称在系统中查找不到");
                }

                if(StringUtils.isEmpty(data[i][5])){

                    checkQues(data[i] , null, null ,"文理科类型不能为空",list);
                    continue;
//                    throw new BusinessException("第"+(1+i)+"行的文理科类型不能为空");
                }
                Integer artsScience = 0;
                if("文科".equals(data[i][5].trim())){
                    artsScience = 1;
                }else if("理科".equals(data[i][5].trim())){
                    artsScience = 2;
                }

                if(StringUtils.isEmpty(data[i][7])){throw new BusinessException("第"+(1+i)+"行的班级编号不能为空"); }
                LessonClassVo c = classMap.get(data[i][7].trim());
                if(c == null){
                    checkQues(data[i] , null, null ,"班级编号:"+data[i][7].trim()+",在系统中查找不到",list);
                    continue;
//                    throw new BusinessException("第"+(1+i)+"行的班级编号在系统中查找不到");
                }

                if(StringUtils.isEmpty(data[i][8])){throw new BusinessException("第"+(i+1)+"行的学生编号不能为空"); }
                Student student = lessonApi.selectStudentByOrganIdStuNo(organId , data[i][8].trim());
                if(student == null){
                    checkQues(data[i] , null, null ,"学生编号:"+data[i][8].trim()+",在系统中查找不到",list);
                    continue;
//                    throw new BusinessException("第"+(1+i)+"行的学生编号在系统中查找不到");
                }

                ExamModelVo em;
                if(rangeMap.containsKey(c.getId()) && examModelIdMap.containsKey(rangeMap.get(c.getId()).getExamModelId())){//存在定制
                    em = examModelIdMap.get(rangeMap.get(c.getId()).getExamModelId());
                }else if(examModelVoMap.containsKey(subject.getId()+""+baseSection.getId()+""+bt.getId()+""+timeType.getId()+""+artsScience+""+c.getBaseLevelId()+"0")){//存在公共模板
                    em = examModelVoMap.get(subject.getId()+""+baseSection.getId()+""+bt.getId()+""+timeType.getId()+""+artsScience+""+c.getBaseLevelId()+"0");
                }else{
                    checkQues(data[i] , null, null ,"该班级找不到试卷模板",list);
                    continue;
//                    throw new BusinessException("班级："+c.getName()+"，没有找到适用的试卷模板,该班级科目为："+subject.getName()+",年级:"+baseSection.getName()+"，学期："+bt.getName()+"，类型："+timeType.getName()+"，文理科："+data[i][5]+"， 班型为："+c.getBaseLevelId());
                }

                if(!quesGroup.containsKey(em.getId()) || em.getQuesCount() != quesGroup.get(em.getId()).size()){
                   throw new BusinessException("找不到试卷："+em.getName()+"找不到相关试题");
                }


                //入库
                List<ExamModelReportQues> quesResult = array2ObjectList(data[i] , quesGroup.get(em.getId()) , em , organId , c.getId() , student.getId() , i+1 , list);
                if(quesResult != null){
                    ExamModelReport report = saveReport(em , quesResult , student.getId() , c.getId() , organId , baseSection.getName());
                    reportList.add(report);
                    reportQuesList.addAll(quesResult);
                    if(reportList.size() == reportBatchSize){//20个学生批量插入
                        examModelReportMapper.insertBatch(reportList);
                        examModelReportQuesMapper.insertBatch(reportQuesList);
                        reportList.clear();
                        reportQuesList.clear();
                    }
                }


            }

            if(reportList.size() > 0){//最后一批不满20个学生批量插入
                examModelReportMapper.insertBatch(reportList);
                examModelReportQuesMapper.insertBatch(reportQuesList);
                reportList.clear();
                reportQuesList.clear();
            }

        }
        excel = failedInfoOfUserImport(list);//失败的数据导出excel
        return excel;
    }

    public List<ExamModelReportQues> array2ObjectList(String[] arr , List<ExamModelQues> quesList, ExamModelVo vo , Long organId , Long classId , Long stuId , int num , List<ExcelErr> errs){
        List<ExamModelReportQues> list = new ArrayList<>();
        Map<Integer , ExamModelQues> map = BeanUtils.toMap(quesList , "sort");
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        int quesSize =  quesList.size();
        if((9+quesSize) >= arr.length || StringUtils.isEmpty(arr[9+quesSize]) || !pattern.matcher(arr[9+quesSize]).matches()
                || (arr.length > (9+quesSize) && !StringUtils.isEmpty(arr[10+quesSize]) && !"0".equals(arr[10+quesSize]))){//为空或不是数字模式
                checkQues(arr , quesList, vo ,"题目数与模板题目数量不匹配",errs);
                return null;
        }
        for (int i = 0 ; i < vo.getQuesCount() ; i++){
            ExamModelReportQues e = new ExamModelReportQues();
            e.setId(Sequence.getSequence().nextId());
            e.setAuthOrganizationId(organId);
            e.setCreateTime(new Date());
            e.setExamModelId(vo.getId());
            BigDecimal defaultScore;
            if(!StringUtils.isEmpty(arr[10+i]) && pattern.matcher(arr[10+i]).matches()){//不为空且是数字模式
                defaultScore = new BigDecimal(Integer.valueOf(arr[10+i]));
                if(map.get(i+1).getScore().compareTo(defaultScore) < 0){
                    checkQues(arr , quesList, vo ,"第"+(i+1)+"题超过题目分数",errs);
                    return null;
                }
            }else{
                checkQues(arr , quesList, vo ,"第"+(i+1)+"题没有录分数",errs);
                return null;
            }
            e.setGetScore(defaultScore.setScale(1, BigDecimal.ROUND_HALF_UP));
            e.setLessonClassId(classId);
            e.setStudentId(stuId);
            e.setExamModelQuesId(map.get(i+1).getId());//通过序号获取试题
            e.setStatus(ExamModelEnums.status.in.getValue());
            list.add(e);
        }

        return list;
    }


    public ExamModelReport saveReport(ExamModelVo em , List<ExamModelReportQues> list , Long stuId , Long classId , Long organId , String sectionName){
        //删除学生原来的统计数据
        examModelReportMapper.deleteByStudentExamClass(stuId , em.getId() , classId);
        //删除学生原来所有题目记录
        examModelReportQuesMapper.deleteByStudentExamClass(stuId , em.getId() , classId);
        //计算总分
        final BigDecimal[] total = new BigDecimal[1];
        list.forEach(examModelReportQues -> total[0] = total[0].add(examModelReportQues.getGetScore()));
//        int total = list.stream().mapToInt(ExamModelReportQues::getGetScore).sum();

        ExamModelReport report = new ExamModelReport();
        report.setAuthOrganizationId(organId);
        report.setBaseSectionId(em.getBaseSectionId());
        report.setGetScore(total[0]);
        report.setLessonClassId(classId);
        report.setStudentId(stuId);
        report.setCreateTime(new Date());
        report.setExamModelId(em.getId());
        report.setBaseSectionName(sectionName);
        report.setId(Sequence.getSequence().nextId());
        report.setStatus(ExamModelEnums.status.in.getValue());
//        examModelReportMapper.insert(report);
//        logger.info("插入学生:"+stuId+"在试卷模板"+em.getName()+"的考试成绩："+total);
//        examModelReportQuesMapper.insertBatch(list);
//        list.forEach(examModelReportQues -> examModelReportQuesMapper.insert(examModelReportQues));
        return report;
    }



	@Override
	public ExamModelReport selectOne(Long authOrganizationId,Long lessonClassId, Long studentId)  {
		return examModelReportMapper.selectOne(authOrganizationId, lessonClassId, studentId);
	}

    @Override
    public RecordDataVo getStudents(Long classId, Long modelId, Long organId) throws Exception {
        RecordDataVo recordDataVo = new RecordDataVo();
        ExamModel e = examModelService.selectByPrimaryKey(modelId);
        LessonClass c = lessonClassAPI.findLessonClassByClassId(classId);
        if(e != null && c != null){
            recordDataVo.setClassId(classId);
            recordDataVo.setModelId(modelId);
            recordDataVo.setModelName(e.getName());
            recordDataVo.setScore(e.getScore());
            recordDataVo.setClassName(c.getName());
            recordDataVo.setActivityId(e.getExamModelActivityId());
            //获取班型ID
            Lesson lesson = lessonAPI.getById(c.getLessonId());
            if(lesson != null){
                recordDataVo.setLevelId(lesson.getBaseLevelId());
            }

            //获取班级在读学生总人数
            Integer studentCount = lessonClassAPI.getStudentCountByClassId(classId);
            recordDataVo.setStuCount(studentCount == null ? 0:studentCount);

            //获取班级学生列表-该模版活动下该班级每个学生的录分状态
            List<StudentRecordVo> stus = getStudentsReports(classId , modelId , organId , e.getExamModelActivityId());
            if(CollectionUtils.isEmpty(stus)){
                recordDataVo.setList(stus);
            }else{

                //排序
//                stus.sort(Comparator.comparing(StudentRecordVo::getSpell));
                Collections.sort(stus , (o1, o2) -> {
                    int result = 0;
                    if(!o1.getSpell().equals(o2.getSpell())){//拼音不同
                        String[] arr = {o1.getSpell() , o2.getSpell()};
                        Arrays.sort(arr);
                        if(o1.getSpell().equals(arr[0])){//数组排序完，第一个还是原来的第一个，代表o1的比较小
                            result = -1;
                        }else {//两个字符发生位置调换
                            result = 1;
                        }
                    }
                    return result;
                });

                //试卷模块列表
                List<ExamModelBlock> blocks = examModelBlockMapper.findBlockByExamModelId(modelId);
                //获取全部题目类型
                List<CommDataConfig> quesTypes = commDataConfigService.findUseByCategory(CommDataConfigEnums.category.questionType.getValue());
                Map<Long , CommDataConfig> quesTypeMap = BeanUtils.toMap(quesTypes , "id");

                //试卷题目列表
                List<ExamModelQues> quesList = examModelQuesService.getByModelId(modelId);
                List<QuesRecordVo> defaultList= new ArrayList<>();
                List<ExamModelBlockRecordVo> default_blockRecordVos = new ArrayList<>();

                //默认题目列表-未录分时默认
                quesList.forEach(ques -> {
                    QuesRecordVo q = new QuesRecordVo();
                    DefindBeanUtils.copyProperties(ques , q);
                    q.setGetScore(BigDecimal.ZERO);
                    q.setQuesId(ques.getId());
                    defaultList.add(q);
                });
                Map<Long , List<QuesRecordVo>> q_map = BeanUtils.toGroup(defaultList , "examModelBlockId");
                blocks.forEach(b -> {
                    ExamModelBlockRecordVo blockRecordVo = new ExamModelBlockRecordVo();
                    DefindBeanUtils.copyProperties(b , blockRecordVo);
                    blockRecordVo.setList(q_map.get(b.getId()));
                    blockRecordVo.setDataQuestionTypeName(quesTypeMap.get(blockRecordVo.getDataQuestionType()).getName());
                    default_blockRecordVos.add(blockRecordVo);
                });

                //模版下学生录分记录
                List<QuesRecordVo> quesRecordVos = examModelReportQuesMapper.getStuQues(classId , modelId , null);
                Map<Long , List<QuesRecordVo>> group = BeanUtils.toGroup(quesRecordVos , "stuId");
                stus.forEach(s -> {
                    if(group.containsKey(s.getStuId())){//学生有录分
                        List<ExamModelBlockRecordVo> stu_blockRecordVos = new ArrayList<>();
                        Map<Long , List<QuesRecordVo>> r_map = BeanUtils.toGroup(group.get(s.getStuId()) , "examModelBlockId");
                        blocks.forEach(b -> {
                            ExamModelBlockRecordVo blockRecordVo = new ExamModelBlockRecordVo();
                            DefindBeanUtils.copyProperties(b , blockRecordVo);
                            blockRecordVo.setList(r_map.get(b.getId()));
                            stu_blockRecordVos.add(blockRecordVo);
                        });
                        s.setList(stu_blockRecordVos);
                    }else if(s.getIsChanged() != null && s.getIsChanged() == 1){//学生更换模板
                        this.detailExamModelChange(s.getModelId() , classId, s);
                    }else{//学生未录分
                        s.setModelScore(e.getScore());
                        s.setModelId(e.getId());
                        s.setModelName(e.getName());
                        s.setList(default_blockRecordVos);
                    }
                });
                recordDataVo.setList(stus);
            }
        }
        return recordDataVo;
    }

    /**
     * 重新设置该学生换模版后的录分数据
     * @param examId
     * @param s
     */
    public void detailExamModelChange(Long examId ,Long classId , StudentRecordVo s) {
        List<ExamModelBlockRecordVo> list = new ArrayList<>();
        List<ExamModelBlock> blocks = examModelBlockMapper.findBlockByExamModelId(examId);

        //模版下学生录分记录
        List<QuesRecordVo> quesRecordVos = examModelReportQuesMapper.getStuQues(classId , examId , s.getStuId());
        if(!CollectionUtils.isEmpty(quesRecordVos)){
            Map<Long , List<QuesRecordVo>> r_map = BeanUtils.toGroup(quesRecordVos , "examModelBlockId");
            blocks.forEach(b -> {
                ExamModelBlockRecordVo blockRecordVo = new ExamModelBlockRecordVo();
                DefindBeanUtils.copyProperties(b , blockRecordVo);
                blockRecordVo.setList(r_map.get(b.getId()));
                list.add(blockRecordVo);
            });
            s.setStatus(quesRecordVos.get(0).getStatus());
        }
        s.setList(list);
    }


    /**
     * 获取班级学生列表-包括对应模板录分情况
     * @param classId
     * @param modelId
     * @param organId
     * @param activityId
     * @return
     */
    public List<StudentRecordVo> getStudentsReports(Long classId, Long modelId, Long organId , Long activityId){
        List<StudentRecordVo> stus = examModelReportMapper.getStudents(classId , modelId , organId);
        List<StudentRecordVo> reports = examModelReportMapper.getStudentsReports(classId , activityId);
        Map<Long , StudentRecordVo> map = BeanUtils.toMap(reports , "stuId");
        stus.forEach(studentRecordVo -> {
            if(map.containsKey(studentRecordVo.getStuId())){
                StudentRecordVo vo = map.get(studentRecordVo.getStuId());
                studentRecordVo.setRecordStatus(1);
                studentRecordVo.setStatus(vo.getStatus());
                studentRecordVo.setIsChanged(modelId.equals(vo.getModelId())? 0:1);
                studentRecordVo.setModelName(vo.getModelName());
                studentRecordVo.setModelId(vo.getModelId());
                studentRecordVo.setModelScore(vo.getModelScore());
            }else {
                studentRecordVo.setStatus(null);
                studentRecordVo.setRecordStatus(0);
            }
            if(!StringUtils.isEmpty(studentRecordVo.getStuName())){
                studentRecordVo.setSpell(PingYinUtil.toPinyin(studentRecordVo.getStuName().trim()));
            }
        });
        return stus;

    }

    @Override
    @Transactional(rollbackFor=Exception.class, timeout=60)
    public void record(Long classId , Long stuId, Long modelId, String[] scores , Long organId) {
        List<ExamModelQues> quesList = examModelQuesService.getByModelId(modelId);
        if(!CollectionUtils.isEmpty(quesList)){
            if(quesList.size() != scores.length){
                throw new BusinessException("分数列表个数与试卷题目数不符！");
            }

            ExamModel e = examModelService.selectByPrimaryKey(modelId);
            if(e == null){throw new BusinessException("找不到试卷数据");}
            BaseSection bs = lessonApi.selectBaseSectionById(e.getBaseSectionId());

            ExamModelReport report = new ExamModelReport();
            report.setId(Sequence.getSequence().nextId());
            report.setStudentId(stuId);
            report.setExamModelId(modelId);
            report.setAuthOrganizationId(organId);
            report.setCreateTime(new Date());
            report.setLessonClassId(classId);
            report.setBaseSectionId(e.getBaseSectionId());
            report.setBaseSectionName(bs == null ? "":bs.getName());
            report.setStatus(ExamModelEnums.status.in.getValue());

            BigDecimal score = BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP);

            //删除学生原来的统计数据
//            examModelReportMapper.deleteByStudentExamClass(stuId , modelId , classId);
            examModelReportMapper.deleteByClassActivity(stuId , e.getExamModelActivityId() , classId);
            //删除学生原来所有题目记录
//            examModelReportQuesMapper.deleteByStudentExamClass(stuId , modelId , classId);
            examModelReportQuesMapper.deleteByClassActivity(stuId , e.getExamModelActivityId() , classId);

            // 核心知识点得分率，先删除再插入
            examModelReportKnowledgeIMapper.deleteByActivityIdClassIdStuId(stuId, e.getExamModelActivityId(), classId);

            for (int i = 0 ; i < scores.length ; i++){
                BigDecimal b = new BigDecimal(scores[i]).setScale(2, BigDecimal.ROUND_HALF_UP);
                ExamModelReportQues q = new ExamModelReportQues();
                q.setId(Sequence.getSequence().nextId());
                q.setStudentId(stuId);
                q.setGetScore(b);
                q.setExamModelId(modelId);
                q.setAuthOrganizationId(organId);
                q.setCreateTime(new Date());
                q.setLessonClassId(classId);
                q.setExamModelQuesId(quesList.get(i).getId());
                q.setStatus(ExamModelEnums.status.in.getValue());
                score = score.add(q.getGetScore());
                examModelReportQuesMapper.insert(q);

                // 插入学生的核心知识点的得分率
                if(ExamModelEnums.commentStyle.INTEGRATED.getValue() == e.getStyle()){
                    String[] knowledgeIList = quesList.get(i).getKnowledgeI().split(";");
                    for (String knowledgeI : knowledgeIList) {
                        ExamModelReportKnowledgeI examModelReportKnowledgeI = new ExamModelReportKnowledgeI();
                        examModelReportKnowledgeI.setId(Sequence.getSequence().nextId());
                        examModelReportKnowledgeI.setAuthOrganizationId(organId);
                        examModelReportKnowledgeI.setExamModelReportId(report.getId());
                        examModelReportKnowledgeI.setLessonClassId(classId);
                        examModelReportKnowledgeI.setStudentId(stuId);
                        examModelReportKnowledgeI.setExamModelId(modelId);
                        examModelReportKnowledgeI.setExamModelQuesId(q.getExamModelQuesId());
                        examModelReportKnowledgeI.setScoringRate((q.getGetScore().divide(quesList.get(i).getScore(), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100))).intValue());
                        examModelReportKnowledgeI.setCreateTime(DateUtil.now());
                        examModelReportKnowledgeI.setKnowledgeI(knowledgeI);

                        examModelReportKnowledgeIMapper.insert(examModelReportKnowledgeI);
                    }
                }
            }

            report.setGetScore(score);
            examModelReportMapper.insert(report);
        }
    }

    @Override
    public void recordMiss(Long classId, Long stuId, Long modelId, Long organId) {
        List<ExamModelQues> quesList = examModelQuesService.getByModelId(modelId);
        if(!CollectionUtils.isEmpty(quesList)){

            ExamModel e = examModelService.selectByPrimaryKey(modelId);
            if(e == null){throw new BusinessException("找不到试卷数据");}
            BaseSection bs = lessonApi.selectBaseSectionById(e.getBaseSectionId());

            //删除学生原来的统计数据
//            examModelReportMapper.deleteByStudentExamClass(stuId , modelId , classId);
            examModelReportMapper.deleteByClassActivity(stuId , e.getExamModelActivityId() , classId);
            //删除学生原来所有题目记录
//            examModelReportQuesMapper.deleteByStudentExamClass(stuId , modelId , classId);
            examModelReportQuesMapper.deleteByClassActivity(stuId , e.getExamModelActivityId() , classId);

            ExamModelReport report = new ExamModelReport();
            report.setId(Sequence.getSequence().nextId());
            report.setStudentId(stuId);
            report.setExamModelId(modelId);
            report.setAuthOrganizationId(organId);
            report.setCreateTime(new Date());
            report.setLessonClassId(classId);
            report.setBaseSectionId(e.getBaseSectionId());
            report.setBaseSectionName(bs == null ? "":bs.getName());
            report.setStatus(ExamModelEnums.status.miss.getValue());
            report.setGetScore(BigDecimal.ZERO);
            examModelReportMapper.insert(report);

            for (int i = 0 ; i < quesList.size() ; i++){
                ExamModelReportQues q = new ExamModelReportQues();
                q.setStudentId(stuId);
                q.setId(Sequence.getSequence().nextId());
                q.setGetScore(BigDecimal.ZERO);
                q.setExamModelId(modelId);
                q.setAuthOrganizationId(organId);
                q.setCreateTime(new Date());
                q.setLessonClassId(classId);
                q.setExamModelQuesId(quesList.get(i).getId());
                q.setStatus(ExamModelEnums.status.miss.getValue());
                examModelReportQuesMapper.insert(q);
            }
        }
    }

    @Override
    public IsExistResp isExist(Long stuId, Long examId, Long classId) {
        ExamModel e = examModelService.selectByPrimaryKey(examId);
        if(e == null){
            throw new BusinessException("没有该试卷信息，请联系管理员。");
        }
        IsExistResp existResp = examModelReportMapper.findStuReportByActivityClass(e.getExamModelActivityId() , stuId , classId);
        if(existResp == null){
            existResp = new IsExistResp();
            existResp.setIsExist(0);
        }else if(existResp.getExamId().equals(examId)){//存在且为同一个模板数据（更新）
            existResp.setIsExist(0);
        }else {
            existResp.setIsExist(1);
        }
        return existResp;
    }

    public HSSFWorkbook excelStudentScoreNew(Boolean isManage, Long authUserId, List<Long> examModelActivityIds, List<Long> baseSchoolIds, Long baseTrimesterId, List<Long> baseSectionIds, List<Long> dataSubjectIds) {
        Integer maxSort = examModelReportMapper.selectMaxSortOfQuestion(isManage, authUserId, examModelActivityIds, baseSchoolIds, baseTrimesterId, baseSectionIds, dataSubjectIds);
        List<Map<String, String>> studentScoreNew = examModelReportMapper.findStudentScoreNew(isManage, authUserId, maxSort, examModelActivityIds, baseSchoolIds, baseTrimesterId, baseSectionIds, dataSubjectIds);
        if(!CollectionUtils.isEmpty(studentScoreNew) && studentScoreNew.size()>50000){
        	throw new BusinessException("数量不能超过5W");
        }
        
        HSSFWorkbook studentScoreExcel = new HSSFWorkbook();

        HSSFSheet sheet = studentScoreExcel.createSheet("导出学生成绩");
        HSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[] { "活动","类型","试卷名称","班型","期数","试卷类型","校区","年级","科目","任课老师","班级编号","班级名称","学生编号","学生名字","考试状态","总分","试卷总分"};
        for (int i = 0; i < titles.length; i++) {
            HSSFCell cell = firstRow.createCell(i);
            cell.setCellValue(titles[i]);
        }

        if(maxSort == null){
            return studentScoreExcel;
        }

        for(int j =  0; j < maxSort; j++ ){
            HSSFCell cell = firstRow.createCell(titles.length + 2*j);
            cell.setCellValue(j + 1 + "得分");

            HSSFCell cell2 = firstRow.createCell(titles.length + 2*j + 1);
            cell2.setCellValue(j + 1 + "满分");
        }

        // 缺考设置为红色
        HSSFCellStyle cellStyle = studentScoreExcel.createCellStyle();
        cellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());
        cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);

        for (int i = 0; i < studentScoreNew.size(); i++ ) {

            Map<String, String> studentScoreMap = studentScoreNew.get(i);
            HSSFRow row = sheet.createRow(i + 1);

            int c = 0;
            HSSFCell cell = row.createCell(c++);
            cell.setCellValue(studentScoreMap.get("activityName"));
            
            cell = row.createCell(c++);
            cell.setCellValue(studentScoreMap.get("rangeType"));
            
            cell = row.createCell(c++);
            cell.setCellValue(studentScoreMap.get("examModelName"));

            cell = row.createCell(c++);
            cell.setCellValue(studentScoreMap.get("baseLevelName"));

            cell = row.createCell(c++);
            cell.setCellValue(studentScoreMap.get("baseTrimesterName"));

            cell = row.createCell(c++);
            cell.setCellValue(studentScoreMap.get("examTimeType"));

            cell = row.createCell(c++);
            cell.setCellValue(studentScoreMap.get("baseSchool"));

            cell = row.createCell(c++);
            cell.setCellValue(studentScoreMap.get("baseSection"));

            cell = row.createCell(c++);
            cell.setCellValue(studentScoreMap.get("dataSubject"));

            cell = row.createCell(c++);
            cell.setCellValue(studentScoreMap.get("teacher"));

            cell = row.createCell(c++);
            cell.setCellValue(studentScoreMap.get("classNum"));

            cell = row.createCell(c++);
            cell.setCellValue(studentScoreMap.get("className"));

            cell = row.createCell(c++);
            cell.setCellValue(studentScoreMap.get("studentNo"));

            cell = row.createCell(c++);
            cell.setCellValue(studentScoreMap.get("studentName"));

            cell = row.createCell(c++);
            cell.setCellValue(studentScoreMap.get("studentStatus"));

            cell = row.createCell(c++);
            if("-".equals(studentScoreMap.get("getScore"))){
                cell.setCellValue(studentScoreMap.get("getScore"));
            }else{
                cell.setCellValue(Double.parseDouble(studentScoreMap.get("getScore")));
            }

            cell = row.createCell(c++);
            cell.setCellValue(Double.parseDouble(String.valueOf(studentScoreMap.get("score"))));

            for(int j = 1 ; j <= maxSort; j++){
                cell = row.createCell(c++);
                if(StringUtils.isEmpty(studentScoreMap.get("g" + j))){
                    break;
                }
                if("-".equals(studentScoreMap.get("g" + j))){
                    cell.setCellValue(studentScoreMap.get("g" + j));
                }else{
                    cell.setCellValue(Double.parseDouble(studentScoreMap.get("g" + j)));
                }

                cell = row.createCell(c++);
                if("-".equals(studentScoreMap.get("s" + j))){
                    cell.setCellValue(studentScoreMap.get("s" + j));
                }else{
                    cell.setCellValue(Double.parseDouble(String.valueOf(studentScoreMap.get("s" + j))));
                }

            }

            if("缺考".equals(studentScoreMap.get("studentStatus"))){
                for(int k = 0 ; k <= titles.length + 2 * maxSort - 1 ; k++){
                    if(null != row.getCell(k)){
                        row.getCell(k).setCellStyle(cellStyle);
                    }
                }
            }
        }

        
        return studentScoreExcel;
    }



    public HSSFWorkbook excelStudentScore(Boolean isManage, Long authUserId, Long examModelActivityId, List<Long> baseSchoolIds, Long baseTrimesterId, List<Long> baseSectionIds, List<Long> dataSubjectIds){

        HSSFWorkbook studentScoreExcel = new HSSFWorkbook();

        HSSFSheet sheet = studentScoreExcel.createSheet("导出学生成绩");

        HSSFRow firstRow = sheet.createRow(0);

        String[] titles = new String[] { "类型","试卷名称","班型","期数","试卷类型","校区","年级","科目","任课老师","班级编号","班级名称","学生编号","学生名字","考试状态","总分","试卷总分"
                ,"1得分","1满分","2得分","2满分","3得分","3满分","4得分","4满分","5得分","5满分","6得分","6满分","7得分","7满分","8得分","8满分","9得分","9满分","10得分","10满分","11得分","11满分","12得分","12满分"
                ,"13得分","13满分","14得分","14满分","15得分","15满分","16得分","16满分","17得分","17满分","18得分","18满分","19得分","19满分","20得分","20满分","21得分","21满分","22得分","22满分","23得分","23满分"
                ,"24得分","24满分","25得分","25满分","26得分","26满分","27得分","27满分","28得分","28满分","29得分","29满分","30得分","30满分"};

        for (int i = 0; i < titles.length; i++) {
            HSSFCell cell = firstRow.createCell(i);
            cell.setCellValue(titles[i]);
        }
        List<ExcelStudentScore> studentScoreList = examModelReportMapper.findStudentScore(isManage, authUserId, examModelActivityId, baseSchoolIds, baseTrimesterId, baseSectionIds, dataSubjectIds);

        // 缺考设置为红色
        HSSFCellStyle cellStyle = studentScoreExcel.createCellStyle();
        cellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());
        cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);


        for (int i = 0; i < studentScoreList.size(); i++ ) {

            ExcelStudentScore ess = studentScoreList.get(i);
            HSSFRow row = sheet.createRow(i + 1);


            int c = 0;
            HSSFCell cell = row.createCell(c++);
            cell.setCellValue(ess.getRangeType());

            cell = row.createCell(c++);
            cell.setCellValue(ess.getExamModelName());

            cell = row.createCell(c++);
            cell.setCellValue(ess.getBaseLevelName());

            cell = row.createCell(c++);
            cell.setCellValue(ess.getBaseTrimesterName());

            cell = row.createCell(c++);
            cell.setCellValue(ess.getExamTimeType());

            cell = row.createCell(c++);
            cell.setCellValue(ess.getBaseSchool());

            cell = row.createCell(c++);
            cell.setCellValue(ess.getBaseSection());

            cell = row.createCell(c++);
            cell.setCellValue(ess.getDataSubject());

            cell = row.createCell(c++);
            cell.setCellValue(ess.getTeacher());

            cell = row.createCell(c++);
            cell.setCellValue(ess.getClassNum());

            cell = row.createCell(c++);
            cell.setCellValue(ess.getClassName());

            cell = row.createCell(c++);
            cell.setCellValue(ess.getStudentNo());

            cell = row.createCell(c++);
            cell.setCellValue(ess.getStudentName());

            cell = row.createCell(c++);
            cell.setCellValue(ess.getStudentStatus());

            cell = row.createCell(c++);
            if("-".equals(ess.getGetScore())){
                cell.setCellValue(ess.getGetScore());
            }else{
                cell.setCellValue(Double.parseDouble(ess.getGetScore()));
            }

            cell = row.createCell(c++);
            cell.setCellValue(Double.parseDouble(ess.getScore()));

            for(int j = 1 ; j <= 30 ; j++){
                cell = row.createCell(c++);
                if("-".equals(getScoreByReflect(ess , j, "g"))){
                    cell.setCellValue(getScoreByReflect(ess , j, "g"));
                }else{
                    cell.setCellValue(Double.parseDouble(getScoreByReflect(ess , j, "g")));
                }

                cell = row.createCell(c++);
                if("-".equals(getScoreByReflect(ess, j, "s"))){
                    cell.setCellValue(getScoreByReflect(ess, j, "s"));
                }else{
                    cell.setCellValue(Double.parseDouble(getScoreByReflect(ess, j, "s")));
                }
            }

            if("缺考".equals(ess.getStudentStatus())){
                for(int k = 0 ; k <= titles.length - 1 ; k++){
                    if(null != row.getCell(k)){
                        row.getCell(k).setCellStyle(cellStyle);
                    }
                }
            }
        }
        return studentScoreExcel;
    }


    /*@Override
    @Transactional(rollbackFor=Exception.class)
    public XSSFWorkbook check(InputStream in , Long organId) throws Exception{
        String[][] data = DataUtils.getData(1 , in);
        List<ExcelErr> list = new ArrayList<>();
        XSSFWorkbook excel = new XSSFWorkbook() ;
        if(data != null && data.length > 0){
            logger.info("成绩导入行数："+data.length);

            *//*List<BaseSchool> schools = lessonApi.getSchoolByOrganId(organId);//机构下所有班级
            Map<String , BaseSchool> schoolMap = BeanUtils.toMap(schools , "name");*//*

            List<BaseTrimester> trimesters = lessonApi.findTrimByOran(organId);//获取机构下所有学期
            Map<String , BaseTrimester> trimesterMap = BeanUtils.toMap(trimesters , "name");

            List<BaseSection> sections = lessonApi.findSectionName(new HashMap<>());//获取所有年级
            Map<String , BaseSection> sectionMap = BeanUtils.toMap(sections , "name");

            List<CommDataConfig> subjects = commDataConfigService.findUseByCategory(CommDataConfigEnums.category.subject.getValue());//获取所有年级
            Map<String , CommDataConfig> subjectMap = BeanUtils.toMap(subjects , "name");

            List<CommDataConfig> timeTypes = commDataConfigService.findUseByCategory(CommDataConfigEnums.category.timeType.getValue());//获取所有期类型
            Map<String , CommDataConfig> timeTypesMap = BeanUtils.toMap(timeTypes , "name");

            *//*List<Student> students = lessonApi.selectStudentByOrganId(organId);//获取机构下所有所学生
            Map<String , Student> studentMap = BeanUtils.toMap(students , "studentNo");*//*

            List<LessonClassVo> classes = lessonApi.findLessonClassByOrganId(organId);
            Map<String , LessonClassVo> classMap = BeanUtils.toMap(classes , "num");

            List<ExamModelVo> examModelVos = examModelService.selectByOrganId(organId);

            //标准试卷
            List<ExamModelVo> stands = examModelVos.stream().filter(e -> e.getRangeType() == ExamModelEnums.rangeType.stand.getValue()).collect(Collectors.toList());
            Map<String , List<ExamModelVo>> examModelVosMap = BeanUtils.toGroup(stands , "keyStr");
            examModelVosMap.forEach((k,v)->{
                if(v.size() > 1){
                    throw new BusinessException("标准模板-keyStr："+k+"对应出多个试卷模板：["+v.stream().map(p -> p.getName()).collect(Collectors.joining(","))+"]");
                }
            });

            //自定义试卷
            List<ExamModelVo> defind = examModelVos.stream().filter(e -> e.getRangeType() == ExamModelEnums.rangeType.defind.getValue()).collect(Collectors.toList());
            Map<String , ExamModelVo> examModelVoMap = BeanUtils.toMap(stands , "keyStr");
            Map<Long , ExamModelVo> examModelIdMap = BeanUtils.toMap(defind , "id");

            List<ExamModelRange> ranges = examModelRangeService.getByOrganId(organId);
            Map<Long , ExamModelRange> rangeMap = BeanUtils.toMap(ranges , "lessonClassId");

            List<ExamModelQues> examModelQues = examModelService.selectQuesByOrganId(organId);
            Map<Long , List<ExamModelQues>> quesGroup = BeanUtils.toGroup(examModelQues , "examModelId");

            List<ExamModelReport> reportList = new ArrayList<>(reportBatchSize);
            List<ExamModelReportQues> reportQuesList = new ArrayList<>();

            for (int i = 0 ; i < data.length ; i++){
                if(StringUtils.isEmpty(data[i][0])){throw new BusinessException("第"+(1+i)+"行的期数不能为空"); }
                BaseTrimester bt = trimesterMap.get(data[i][0].trim());
                if(bt == null){throw new BusinessException("第"+(1+i)+"行的期数名称:"+data[i][0].trim()+",在系统中查找不到"); }

                if(StringUtils.isEmpty(data[i][1])){throw new BusinessException("第"+(1+i)+"行的类型不能为空"); }
                CommDataConfig timeType = timeTypesMap.get(data[i][1].trim());
                if(timeType == null){throw new BusinessException("第"+(1+i)+"行的类型名称在系统中查找不到"); }

                *//*if(StringUtils.isEmpty(data[i][2])){throw new BusinessException("第"+i+"行的校区不能为空"); }
                BaseSchool bs = schoolMap.get(data[i][2]);
                if(bs == null){throw new BusinessException("第"+i+"行的校区名称在系统中查找不到"); }*//*

                if(StringUtils.isEmpty(data[i][3])){throw new BusinessException("第"+(1+i)+"行的年级不能为空"); }
                BaseSection baseSection = sectionMap.get(data[i][3]);
                if(baseSection == null){throw new BusinessException("第"+(1+i)+"行的年级名称在系统中查找不到"); }

                if(StringUtils.isEmpty(data[i][4])){throw new BusinessException("第"+(1+i)+"行的科目不能为空"); }
                CommDataConfig subject = subjectMap.get(data[i][4]);
                if(subject == null){throw new BusinessException("第"+(1+i)+"行的科目名称在系统中查找不到"); }

                if(StringUtils.isEmpty(data[i][5])){throw new BusinessException("第"+(1+i)+"行的文理科类型不能为空"); }
                Integer artsScience = 0;
                if("文科".equals(data[i][5])){
                    artsScience = 1;
                }else if("理科".equals(data[i][5])){
                    artsScience = 2;
                }

                if(StringUtils.isEmpty(data[i][7])){throw new BusinessException("第"+(1+i)+"行的班级编号不能为空"); }
                LessonClassVo c = classMap.get(data[i][7]);
                if(c == null){throw new BusinessException("第"+(1+i)+"行的班级编号在系统中查找不到"); }

                if(StringUtils.isEmpty(data[i][8])){throw new BusinessException("第"+(i+1)+"行的学生编号不能为空"); }
                Student student = lessonApi.selectStudentByOrganIdStuNo(organId , data[i][8]);
                if(student == null){throw new BusinessException("第"+(1+i)+"行的学生编号在系统中查找不到"); }

                ExamModelVo em;
                if(rangeMap.containsKey(c.getId()) && examModelIdMap.containsKey(rangeMap.get(c.getId()).getExamModelId())){//存在定制
                    em = examModelIdMap.get(rangeMap.get(c.getId()).getExamModelId());
                }else if(examModelVoMap.containsKey(subject.getId()+""+baseSection.getId()+""+bt.getId()+""+timeType.getId()+""+artsScience+""+c.getBaseLevelId()+"0")){//存在公共模板
                    em = examModelVoMap.get(subject.getId()+""+baseSection.getId()+""+bt.getId()+""+timeType.getId()+""+artsScience+""+c.getBaseLevelId()+"0");
                }else{
                    throw new BusinessException("第"+i+"行班级："+c.getName()+"，没有找到适用的试卷模板,该班级科目为："+subject.getName()+",年级:"+baseSection.getName()+"，学期："+bt.getName()+"，类型："+timeType.getName()+"，文理科："+data[i][5]+"， 班型为："+c.getBaseLevelId());
                }

                if(!quesGroup.containsKey(em.getId()) || em.getQuesCount() != quesGroup.get(em.getId()).size()){
                    throw new BusinessException("找不到试卷："+em.getName()+"找不到相关试题");
                }

                ExcelErr err  = checkQues(data[i] , quesGroup.get(em.getId()) , em);
                if(err != null){
                    list.add(err);
                }
            }

        }
        excel = failedInfoOfUserImport(list);
        return excel;
    }*/

    public void checkQues(String[] arr , List<ExamModelQues> quesList, ExamModelVo vo , String reason , List<ExcelErr> list){
        ExcelErr ee = new ExcelErr();
        ee.setClassName(arr[6]);
        ee.setClassNum(arr[7]);
        ee.setWal(arr[5]);
        ee.setType(arr[1]);
        ee.setTerm(arr[0]);
        ee.setSub(arr[4]);
        ee.setStuName(arr[9]);
        ee.setStuNum(arr[8]);
        ee.setSec(arr[3]);
        ee.setSc(arr[2]);
        ee.setModelName(vo == null ? "":vo.getName());
        ee.setReason(reason);
        setByReflect(ee , arr , quesList);
        list.add(ee);
    }

    public XSSFWorkbook failedInfoOfUserImport(List<ExcelErr> userExcelList){

        XSSFWorkbook excel = new XSSFWorkbook();

        XSSFSheet sheet = excel.createSheet("导入失败信息");

        XSSFRow firstRow = sheet.createRow(0);

        String[] titles = new String[] { "期数","类型","校区","年纪","科目","文理科","班级名称","班级编号","学生编号","学生姓名"
                ,"得分1","得分2","得分3","得分4","得分5","得分6","得分7","得分8","得分9","得分10","得分11","得分12","得分13",
                "模板第1题","模板第2题","模板第3题","模板第4题","模板第5题","模板第6题","模板第7题","模板第8题","模板第9题","模板第10题","模板第11题","模板第12题","模板第13题",
                "模板名称","失败原因"};

        for (int i = 0; i < titles.length; i++) {
            XSSFCell cell = firstRow.createCell(i);

            // 失败原因设置为红色
            if(i == titles.length -1){
                XSSFCellStyle cellStyle = excel.createCellStyle();
                cellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
                cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
                cell.setCellStyle(cellStyle);
            }
            cell.setCellValue(titles[i]);
        }

        for (int i = 0; i < userExcelList.size(); i++ ) {

            ExcelErr ee = userExcelList.get(i);

            XSSFRow row = sheet.createRow(i + 1);

            int c = 0;
            XSSFCell cell = row.createCell(c++);
            cell.setCellValue(ee.getTerm());

            cell = row.createCell(c++);
            cell.setCellValue(ee.getType());

            cell = row.createCell(c++);
            cell.setCellValue(ee.getSc());

            cell = row.createCell(c++);
            cell.setCellValue(ee.getSec());

            cell = row.createCell(c++);
            cell.setCellValue(ee.getSub());

            cell = row.createCell(c++);
            cell.setCellValue(ee.getWal());

            cell = row.createCell(c++);
            cell.setCellValue(ee.getClassName());

            cell = row.createCell(c++);
            cell.setCellValue(ee.getClassNum());

            cell = row.createCell(c++);
            cell.setCellValue(ee.getStuNum());

            cell = row.createCell(c++);
            cell.setCellValue(ee.getStuName());

            for(int j = 1 ; j < 14 ; j++){
                cell = row.createCell(c++);
                cell.setCellValue(getByReflect(ee , j, "g") );
            }
            for(int j = 1 ; j < 14 ; j++){
                cell = row.createCell(c++);
                cell.setCellValue(getByReflect(ee , j, "s") );
            }

            cell = row.createCell(c++);
            cell.setCellValue(ee.getModelName());

            cell = row.createCell(c++);
            // 失败原因设置为红色
            XSSFCellStyle cellStyle = excel.createCellStyle();
            cellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
            cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
            cell.setCellStyle(cellStyle);
            cell.setCellValue(ee.getReason());


//            cell = row.createCell(c++);
//            // 失败原因设置为红色
//            XSSFCellStyle cellStyle = excel.createCellStyle();
//            cellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());
//            cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
//            cell.setCellStyle(cellStyle);
//            cell.setCellValue(userExcel.getFailedReason());
        }
        return excel;
    }

    public void setByReflect(ExcelErr ee , String[] arr , List<ExamModelQues> quesList){
        try {
            for (int i = 1 ; i < 14 ; i++){
                Field field1,field2;
                field2 = ee.getClass().getDeclaredField("g"+i);
                field2.setAccessible(true);

                if(quesList != null){
                    field1 = ee.getClass().getDeclaredField("s"+i);
                    field1.setAccessible(true);
                    try {
                        field1.set(ee, quesList.size() < i-1 ? "":quesList.get(i-1).getScore()+"");
                    }catch (IndexOutOfBoundsException e){
                        field1.set(ee, "");
                    }

                }

                try {
                    field2.set(ee, arr.length < 9+1 ? "":arr[9+i]);
                }catch (IndexOutOfBoundsException e){
                    field2.set(ee, "");
                }
//                field1.set(ee, quesList.size() < i-1 ? "":quesList.get(i-1).getScore()+"");
//                field2.set(ee, arr.length < 9+1 ? "":arr[9+i]);r
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String getByReflect(ExcelErr ee , int i , String str){
        Field f = null;
        String result = "";
        try {
            f = ee.getClass().getDeclaredField(str+i);
            f.setAccessible(true);
            if(f.get(ee) != null){
                result =  f.get(ee).toString();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public String getScoreByReflect(ExcelStudentScore ess , int i , String str){
        Field f = null;
        String result = "";
        try {
            f = ess.getClass().getDeclaredField(str+i);
            f.setAccessible(true);
            if(f.get(ess) != null){
                result = f.get(ess).toString();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

	@Override
	public boolean checkReportUse(Long id) {
		Integer c=examModelReportMapper.checkReportUse(id);		
		return c>0;
	}
}